package it.univpm.diiga.semanticsearch.ricerca;
import it.univpm.diiga.semanticsearch.configurazione.Configuration;
import it.univpm.diiga.semanticsearch.gestione.GestioneRepository;
import it.univpm.diiga.semanticsearch.gestione.GestioneRepositoryView;
import it.univpm.diiga.semanticsearch.servizi.Link;

import java.awt.Desktop;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import java.net.SocketTimeoutException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;
import javax.swing.table.DefaultTableModel;


public class RicercaView extends JFrame {

	private JTable table;
	final public JButton searchButton;
	private List<Link> resultRepo;
	private List<Link> resultWeb;
	private List<Link> resultTotal;
	private List<Link> selectedResult;
	private JScrollPane resultPane;
	private JButton saveButton;
	private JButton addLocalRepositoryButton;
	private JCheckBox localRepoCheckBox,publicRepoCheckBox,defaultRepoCheckBox,webCheckBox;
	private JProgressBar progressBar;
	private JLabel foundResult; 
	private Thread repoSearchThread;
	private Thread webSearchThread;
	final JMenuItem settingsMenu, managerRepositoryMenu;
	private JTextField keyword, proxy, proxyPort;

	
	boolean visibleElement=false;
	
	/**
	 * Create the frame
	 */
	public RicercaView() {
		super();
		//getConfiguration();
		
		getContentPane().setLayout(null);
		setResizable(false);
		setBounds(100, 100, 722, 673);
		setDefaultCloseOperation(this.EXIT_ON_CLOSE);

		keyword = new JTextField();
		keyword.addKeyListener(new KeyAdapter() {
			public void keyPressed(final KeyEvent e) {
				if (e.getKeyCode() == KeyEvent.VK_ENTER){
						showResult();
				}
			}
		});
		keyword.setBounds(193, 41, 192, 25);
		getContentPane().add(keyword);
		
		foundResult = new JLabel();
		foundResult.setBounds(237, 394, 165, 15);
		foundResult.setVisible(false);
		foundResult.setText("No match found");
		getContentPane().add(foundResult);
		
		progressBar = new JProgressBar(0,100);
		progressBar.setBounds(539, 570, 74, 25);


		searchButton = new JButton();
		searchButton.addActionListener(new ActionListener() {
			public void actionPerformed(final ActionEvent e) {
				showResult();
			}
		});
		
		searchButton.setText("Search");
		searchButton.setBounds(408, 41, 111, 25);
		getContentPane().add(searchButton);
		
	
		saveButton = new JButton();
		saveButton.addActionListener(new ActionListener() {
			public void actionPerformed(final ActionEvent e) {
				selectedResult=new ArrayList<Link>();
				//preleva risultati e li manda a save result
				int[] indexSelectedResult= table.getSelectedRows();
				resultRepo.addAll(resultWeb);
				for (int i=0;i<indexSelectedResult.length;i++){
					int indexResult =table.convertRowIndexToModel(indexSelectedResult[i]);
					selectedResult.add(resultTotal.get(indexResult));
					
				}
				if (indexSelectedResult.length>0){
					final SaveResultView saveView=new SaveResultView(selectedResult);	
					//saveView.setRicerca(ricerca);
					saveView.setVisible(true);
				}
				else{
					JOptionPane.showMessageDialog(null, "Select search result","Save result",JOptionPane.ERROR_MESSAGE);
				}
				
			}
		});
		saveButton.setText("Save Result");
		saveButton.setBounds(76, 570, 111, 25);
		getContentPane().add(saveButton);
		saveButton.setVisible(false);
		
		

		resultPane = new JScrollPane();
		resultPane.setBounds(76, 288, 537, 276);
		getContentPane().add(resultPane);
		resultPane.setVisible(false);
		

		addLocalRepositoryButton = new JButton();
		addLocalRepositoryButton.setText("Add to Local Repo");
		addLocalRepositoryButton.setBounds(195, 570, 157, 25);
		getContentPane().add(addLocalRepositoryButton);
		addLocalRepositoryButton.addActionListener(new ActionListener() {
			public void actionPerformed(final ActionEvent e) {
				
				addToLocalRepo();
			}
		});
		addLocalRepositoryButton.setVisible(false);

		localRepoCheckBox = new JCheckBox();
		localRepoCheckBox.setText("Local Repository");
		localRepoCheckBox.setBounds(125, 111, 151, 23);
		getContentPane().add(localRepoCheckBox);

		publicRepoCheckBox = new JCheckBox();
		publicRepoCheckBox.setText("Public Repository");
		publicRepoCheckBox.setBounds(125, 151, 151, 23);
		getContentPane().add(publicRepoCheckBox);

		defaultRepoCheckBox = new JCheckBox();
		defaultRepoCheckBox.setText("Default Repository");
		defaultRepoCheckBox.setBounds(125, 191, 151, 23);
		getContentPane().add(defaultRepoCheckBox);

		webCheckBox = new JCheckBox();
		webCheckBox.setText("Web");
		webCheckBox.setBounds(125, 231, 151, 23);
		getContentPane().add(webCheckBox);

		final JLabel keywordLabel = new JLabel();
		keywordLabel.setFont(new Font("Lucida Grande", Font.BOLD, 14));
		keywordLabel.setText("Keyword:");
		keywordLabel.setBounds(112, 46, 68, 20);
		getContentPane().add(keywordLabel);

		final JPanel optionPane = new JPanel();
		optionPane.setBorder(new TitledBorder(null, "Search in", TitledBorder.DEFAULT_JUSTIFICATION, TitledBorder.DEFAULT_POSITION, null, null));
		optionPane.setBounds(112, 84, 273, 186);
		getContentPane().add(optionPane);

		final JMenuBar menuBar = new JMenuBar();
		setJMenuBar(menuBar);

		final JMenu fileMenu = new JMenu();
		fileMenu.setText("File");
		menuBar.add(fileMenu);

		final JMenuItem newItemMenuItem = new JMenuItem();
		newItemMenuItem.addActionListener(new ActionListener() {
			public void actionPerformed(final ActionEvent e) {
				//JOptionPane p=new JOptionPane();
				if(JOptionPane.showConfirmDialog(null, "Are you sure ?","Exit confirm", 0)==0)
					dispose();
			}
		});
		newItemMenuItem.setText("Exit");
		fileMenu.add(newItemMenuItem);

		final JMenu editMenu = new JMenu();
		editMenu.setText("Edit");
		menuBar.add(editMenu);
		
	  	final JDialog popup = new JDialog();
		//final JPanel popup = new JPanel();
	  	popup.setLayout(null);
	  	popup.setBounds(314, 99, 233, 220);
		//getContentPane().add(popup);

		settingsMenu = new JMenuItem();
		//final RicercaView rw=this;
		settingsMenu.addActionListener(new ActionListener() {
			public void actionPerformed(final ActionEvent e) {
					//popup.setVisible(true);							//SETTING
					Settings settingDialog = new Settings();
					settingDialog.setModal(true);
					settingDialog.setVisible(true);
				
			}
		});
		settingsMenu.setText("Settings");
		editMenu.add(settingsMenu);
		
		managerRepositoryMenu = new JMenuItem();
		managerRepositoryMenu.addActionListener(new ActionListener() {
			public void actionPerformed(final ActionEvent e) {
					//popup.setVisible(true);
					try{
					    GestioneRepositoryView grv = new GestioneRepositoryView();
						//Settings dialog = new Settings(ricerca);
						grv.frmGestioneRepository.setVisible(true);
				    } catch (Exception ex) {
					  	ex.printStackTrace();
					  	
				    	JOptionPane.showMessageDialog(null, "Wrong local file name or incomplete XML","Error", JOptionPane.ERROR_MESSAGE);
					  		//e.printStackTrace();
				  	}

					

			}
		});
		managerRepositoryMenu.setText("Manage Local Repository");
		editMenu.add(managerRepositoryMenu);

		final JMenu menu = new JMenu();
		menu.setText("?");
		menuBar.add(menu);

		final JMenuItem newItemMenuItem_2 = new JMenuItem();
		menu.add(newItemMenuItem_2);
		newItemMenuItem_2.setText("Help");
		newItemMenuItem_2.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				File f=new File("help/Manuale utente.pdf");
				try {
					java.awt.Desktop.getDesktop().open(f);
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				
			}});

		final JMenuItem newItemMenuItem_3 = new JMenuItem();
		menu.add(newItemMenuItem_3);
		newItemMenuItem_3.setText("About us");
		newItemMenuItem_3.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				JDialog dialog = new JDialog();
				dialog.setModal(true);
				
				Toolkit tk = Toolkit.getDefaultToolkit();
				Dimension screenSize = tk.getScreenSize();
				int screenHeight = screenSize.height;
				int screenWidth = screenSize.width;
				dialog.setSize(400, 220);
				dialog.setLocation(screenWidth / 4, screenHeight / 4);
				dialog.setLocationRelativeTo(getRootPane());
				 
				dialog.setTitle("About us"); 
				dialog.setResizable(false);
				dialog.getContentPane().setLayout(null);
				
				final JLabel developLabel = new JLabel();
				developLabel.setFont(new Font("Lucida Grande", Font.BOLD, 13));
				developLabel.setText("Developed by:");
				developLabel.setBounds(35, 80, 137, 15);
				dialog.getContentPane().add(developLabel);

				final JLabel giovanniBelelliLabel = new JLabel();
				giovanniBelelliLabel.setText("Giovanni Belelli");
				giovanniBelelliLabel.setBounds(35, 106, 194, 15);
				dialog.getContentPane().add(giovanniBelelliLabel);

				final JLabel giuseppePrencipeLabel = new JLabel();
				giuseppePrencipeLabel.setText("Giuseppe Prencipe");
				giuseppePrencipeLabel.setBounds(35, 131, 194, 15);
				dialog.getContentPane().add(giuseppePrencipeLabel);

				final JLabel marcoTrinastichLabel = new JLabel();
				marcoTrinastichLabel.setText("Marco Trinastich");
				marcoTrinastichLabel.setBounds(35, 156, 194, 15);
				dialog.getContentPane().add(marcoTrinastichLabel);

				ImageIcon titleImage = new ImageIcon("images/title.png");
				final JLabel titleLabel = new JLabel();
				titleLabel.setIcon(titleImage);
				titleLabel.setBounds(65, 17, 276, 37);
				dialog.getContentPane().add(titleLabel);

				ImageIcon iconImage = new ImageIcon("images/icon.png");
				final JLabel iconLabel = new JLabel();
				iconLabel.setIcon(iconImage);
				iconLabel.setBounds(236, 84, 75, 90);
				dialog.getContentPane().add(iconLabel);
				 
				dialog.setVisible(true);

				
			}});
		
				
		}
	
	public void getConfiguration() {
		
		try {
			Configuration.findLocalConfiguration();			
		}catch (Configuration.RemoteExc e){
			JOptionPane.showMessageDialog(null, "Incomplete XML remote file configuration ","File config error", JOptionPane.ERROR_MESSAGE);

		} 
		catch (Configuration.LocalExc e){
			JOptionPane.showMessageDialog(null, "Incomplete XML local configuration - ","File config error", JOptionPane.ERROR_MESSAGE);
		}
		catch (Configuration.FileConfigExc e){
			JOptionPane.showMessageDialog(null, "Incomplete XML file configuration","File config error", JOptionPane.ERROR_MESSAGE);

		}
		catch(Exception e){
			JOptionPane.showMessageDialog(null, "Server error\nError in XML file server configuration","Error", JOptionPane.ERROR_MESSAGE);
		}

	}

	private void viewResultElement(boolean visible){
		
		//foundResult.setVisible(!visible);
		resultPane.setVisible(visible);
		saveButton.setVisible(visible);
		addLocalRepositoryButton.setVisible(visible);
		if (visible){
			resultPane.setViewportView(table);
			table.setFillsViewportHeight(true);
		}
	}
	
	private void showResult(){
		//esegue ricerca
		getConfiguration();
		if (!keyword.getText().equals("") && ( localRepoCheckBox.isSelected() || publicRepoCheckBox.isSelected() || defaultRepoCheckBox.isSelected() || webCheckBox.isSelected())){
				
				resultRepo=new ArrayList<Link>();
				resultWeb=new ArrayList<Link>();

				progressBar.setVisible(true);
				progressBar.setIndeterminate(true);
				
				getContentPane().add(progressBar);
				
				visibleElement=false;
				foundResult.setVisible(false);
				viewResultElement(visibleElement);
				
				//model=new Model();
				final DefaultTableModel model = new DefaultTableModel(){
					
					 public boolean isCellEditable(int row, int column) {
					        return false;
					    }
					
				}; 
				String[] columnNames = {"Service Name",
										"Repository"};
				
				model.setColumnIdentifiers(columnNames);

				//model.addRow(new Object[]{"v1", "v2"});
				
				table = new JTable(model);
				table.addMouseListener(new MouseAdapter() {

					public void mouseClicked(MouseEvent e) {
						if (e.getClickCount() == 2) {
							JTable target = (JTable) e.getSource();
							//int row = target.getSelectedRow();
							//int column = target.getSelectedColumn();
							int row = target.rowAtPoint( e.getPoint() );
							int column = target.columnAtPoint( e.getPoint() );
							int indexResult = table.convertRowIndexToModel(row);
							//selectedResult.add(resultTotal.get(indexResult));
							URI uri;
							try {
								uri = new URI(resultTotal.get(indexResult).getServLink());
								Desktop.getDesktop().browse(uri);
							} catch (Exception e1) {
								// TODO Auto-generated catch block
								JOptionPane.showMessageDialog(null, "File not found","Error", JOptionPane.ERROR_MESSAGE);
								e1.printStackTrace();
							}
						}
					}
				});
				
				/*managerRepositoryMenu.addActionListener(new ActionListener() {
					public void actionPerformed(final ActionEvent e) {
							//popup.setVisible(true);
							try{
							    GestioneRepositoryView grv = new GestioneRepositoryView();
								//Settings dialog = new Settings(ricerca);
								//grv.frmGestioneRepository.setVisible(true);
						    } catch (Exception ex) {
							  	JOptionPane.showMessageDialog(null, "Wrong local file name or incomplete XML","Error", JOptionPane.ERROR_MESSAGE);
							  		//e.printStackTrace();
						  	}

							

					}
				});*/
				
				final Object row[]= new Object[columnNames.length];
				
				resultTotal=new ArrayList<Link>();
				
				if (localRepoCheckBox.isSelected() || publicRepoCheckBox.isSelected() || defaultRepoCheckBox.isSelected()){
					repoSearchThread = new Thread(){
						
						public void run() {
							try{
								RicercaRepository ricRepo=new RicercaRepository(localRepoCheckBox.isSelected(),defaultRepoCheckBox.isSelected(),publicRepoCheckBox.isSelected());
								//ricRepo.getRemoteConfiguration();
							
								resultRepo=ricRepo.execSearch(keyword.getText());
								if (resultRepo!=null){
									if (resultRepo.size()>0){
										visibleElement=true;
										
									}
									for (int i=0;i<resultRepo.size();i++){
										row[0]=resultRepo.get(i).getServName() != null ? resultRepo.get(i).getServName() : "undefined" ;
										//row[1]=result.get(i).getServLink() != null ? result.get(i).getServLink() : "" ;
										row[1]=resultRepo.get(i).getServRepo() != null ? resultRepo.get(i).getServRepo() : "undefined Repo" ;
										model.addRow(row);
										resultTotal.add(resultRepo.get(i));
										
									}
									viewResultElement(visibleElement);
									foundResult.setVisible(!visibleElement);
									
									
									if (webSearchThread==null ||  !webSearchThread.isAlive()){
										progressBar.setValue(100);
										progressBar.setIndeterminate(false);
									}
								 }
								}
								catch (SocketTimeoutException e) {
									// TODO Auto-generated catch block
									progressBar.setValue(100);
									progressBar.setIndeterminate(false);
									progressBar.setVisible(false);
									JOptionPane.showMessageDialog(null, "Time out","Error", JOptionPane.ERROR_MESSAGE);
	
								}
								catch (Configuration.RemoteExc e) {
									// TODO Auto-generated catch block
									progressBar.setValue(100);
									progressBar.setIndeterminate(false);
									progressBar.setVisible(false);
									JOptionPane.showMessageDialog(null, "Remote server error","Error", JOptionPane.ERROR_MESSAGE);
	
								}
								catch (Exception e) {
									// TODO Auto-generated catch block
									progressBar.setValue(100);
									progressBar.setIndeterminate(false);
									progressBar.setVisible(false);
									//JOptionPane.showMessageDialog(null, "Error","Error", JOptionPane.ERROR_MESSAGE);
									e.printStackTrace();
	
								}
								
						
			         }
					
					};
					repoSearchThread.setPriority(10);
					repoSearchThread.start();
					
				}
				if (webCheckBox.isSelected()){
					webSearchThread = new Thread(){
				         public void run() {
								
								try {
									RicercaWeb ricWeb = new RicercaWeb();
									resultWeb=ricWeb.execSearch(keyword.getText());
						        	 	
						        	if (resultWeb!=null){
										if (resultWeb.size()>0){
											visibleElement=true;
											
										}
										viewResultElement(visibleElement);
										foundResult.setVisible(!visibleElement);
										
										for (int i=0;i<resultWeb.size();i++){

											if (resultWeb.get(i).getServName()!=null)
												row[0]=resultWeb.get(i).getServName(); 
											else 
												row[0]="undefined" ;
											//row[1]=result.get(i).getServLink() != null ? result.get(i).getServLink() : "" ;
											if (resultWeb.get(i).getServRepo() != null)
												row[1]=resultWeb.get(i).getServRepo(); 
											else 
												row[1]="undefined Repo";
											model.addRow(row);
											resultTotal.add(resultWeb.get(i));
										}
										/*viewResultElement(visibleElement);
										foundResult.setVisible(!visibleElement);
										*/
										if (repoSearchThread==null || !repoSearchThread.isAlive()){
											progressBar.setValue(100);
											progressBar.setIndeterminate(false);
										}
						        	}
								} catch (SocketTimeoutException e) {
									// TODO Auto-generated catch block
									progressBar.setValue(100);
									progressBar.setIndeterminate(false);
									progressBar.setVisible(false);
									JOptionPane.showMessageDialog(null, "Time out","Error", JOptionPane.ERROR_MESSAGE);
									e.printStackTrace();
								}catch (Configuration.LocalExc e) {
										// TODO Auto-generated catch block
										progressBar.setValue(100);
										progressBar.setIndeterminate(false);
										progressBar.setVisible(false);
										JOptionPane.showMessageDialog(null, "Local server error","Error", JOptionPane.ERROR_MESSAGE);
										
								
								}catch (Configuration.RemoteExc e) {
									// TODO Auto-generated catch block
									progressBar.setValue(100);
									progressBar.setIndeterminate(false);
									progressBar.setVisible(false);
									JOptionPane.showMessageDialog(null, "Remote server error","Error", JOptionPane.ERROR_MESSAGE);
	
								}catch (Exception e) {
									// TODO Auto-generated catch block
									progressBar.setValue(100);
									progressBar.setIndeterminate(false);
									progressBar.setVisible(false);
									/*JOptionPane.showMessageDialog(null, "Error","Error", JOptionPane.ERROR_MESSAGE);*/
									JOptionPane.showMessageDialog(null, "Remote server error","Error", JOptionPane.ERROR_MESSAGE);

								}
								
							
				         }
						
					};
					webSearchThread.setPriority(6);
					webSearchThread.start();
			
					
				}
		}
		else{
			JOptionPane.showMessageDialog(null, "Insert the keyword and select the source option","Insert option", JOptionPane.ERROR_MESSAGE);
		}
		
	
	}
	

	private void addToLocalRepo(){
		selectedResult=new ArrayList<Link>();
		//preleva risultati e li manda a save result
		int[] indexSelectedResult= table.getSelectedRows();
		resultRepo.addAll(resultWeb);
		for (int i=0;i<indexSelectedResult.length;i++){
			int indexResult =table.convertRowIndexToModel(indexSelectedResult[i]);
			selectedResult.add(resultTotal.get(indexResult));
			
		}
		if (indexSelectedResult.length>0){
			GestioneRepository gr=new GestioneRepository();
			for (int i=0; i<selectedResult.size(); i++)
				try {
					gr.addRepository(selectedResult.get(i), -1);
					JOptionPane.showMessageDialog(null, "Services added to local repository","Services",JOptionPane.INFORMATION_MESSAGE);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					JOptionPane.showMessageDialog(null, "Wrong local file name or incomplete XML","Error", JOptionPane.ERROR_MESSAGE);
					//e.printStackTrace();
				}
		}
		else{
			JOptionPane.showMessageDialog(null, "Select search result","Save result",JOptionPane.ERROR_MESSAGE);
		}
	}
	
 
	

}

